{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "635d8ebb",
   "metadata": {},
   "source": [
    "# LangGrpah Subgraph\n",
    "\n",
    "- Author: [Sunyoung Park (architectyou)](https://github.com/architectyou)\n",
    "- Design: \n",
    "- Peer Review: \n",
    "- Proofread : [Chaeyoon Kim](https://github.com/chaeyoonyunakim)\n",
    "- This is a part of [LangChain Open Tutorial](https://github.com/LangChain-OpenTutorial/LangChain-OpenTutorial)\n",
    "\n",
    "[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/LangChain-OpenTutorial/LangChain-OpenTutorial/blob/main/17-LangGraph/01-Core-Features/13-LangGraph-Subgraph.ipynb)[![Open in GitHub](https://img.shields.io/badge/Open%20in%20GitHub-181717?style=flat-square&logo=github&logoColor=white)](https://github.com/LangChain-OpenTutorial/LangChain-OpenTutorial/blob/main/17-LangGraph/01-Core-Features/13-LangGraph-Subgraph.ipynb)\n",
    "## Overview\n",
    "\n",
    "Using **SubGraphs** allows you to build complex systems containing multiple components, where these components themselves can become graphs. A common use case for **SubGraphs** is building multi-agent systems.\n",
    "\n",
    "The main consideration when adding **SubGraphs** is how the parent graph and SubGraph communicate, specifically how they pass state to each other during graph execution.\n",
    "\n",
    "- There are two scenarios:\n",
    "1. When the parent graph and ```subgraph``` **share schema keys**. In this case, you can add nodes with the compiled ```subgraph```.\n",
    "2. When the parent graph and ```subgraph``` have **different schemas**. In this case, you need to add a **node function** that calls the ```subgraph```.\n",
    "\n",
    "This is useful when the parent graph and ```subgraph``` have different state schemas and the state needs to be transformed before and after calling the ```subgraph```.\n",
    "\n",
    "I'll show you how to add subgraphs for each scenario below.\n",
    "\n",
    "![langgraph-subgraph](./assets/13-langgraph-subgraph.png)\n",
    "\n",
    "### Table of Contents\n",
    "\n",
    "- [Overview](#overview)\n",
    "- [Environment Setup](#environment-setup)\n",
    "- [Case 1: When Sharing Schema Keys](#case-1-when-sharing-schema-keys)\n",
    "- [Case 2: When Not Sharing Schema Keys](#case-2-when-not-sharing-schema-keys)\n",
    "\n",
    "### References\n",
    "\n",
    "- [How to add and use subgraphs](https://langchain-ai.github.io/langgraph/how-tos/subgraph/)\n",
    "- [How to visualize your graph](https://langchain-ai.github.io/langgraph/how-tos/visualization/#set-up-graph)\n",
    "----"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c6c7aba4",
   "metadata": {},
   "source": [
    "## Environment Setup\n",
    "\n",
    "Setting up your environment is the first step. See the [Environment Setup](https://wikidocs.net/257836) guide for more details.\n",
    "\n",
    "\n",
    "**[Note]**\n",
    "\n",
    "The langchain-opentutorial is a package of easy-to-use environment setup guidance, useful functions and utilities for tutorials.\n",
    "Check out the  [```langchain-opentutorial```](https://github.com/LangChain-OpenTutorial/langchain-opentutorial-pypi) for more details."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "21943adb",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%capture --no-stderr\n",
    "%pip install langchain-opentutorial"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "f25ec196",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Install required packages\n",
    "from langchain_opentutorial import package\n",
    "\n",
    "package.install(\n",
    "    [\n",
    "        \"langgraph\",\n",
    "        \"langchain-opentutorial\"\n",
    "    ],\n",
    "    verbose=False,\n",
    "    upgrade=False,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "690a9ae0",
   "metadata": {},
   "source": [
    "You can set API keys in a ```.env``` file or set them manually.\n",
    "\n",
    "[Note] If you’re not using the ```.env``` file, no worries! Just enter the keys directly in the cell below, and you’re good to go."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "327c2c7c",
   "metadata": {},
   "outputs": [],
   "source": [
    "from dotenv import load_dotenv\n",
    "from langchain_opentutorial import set_env\n",
    "\n",
    "# Attempt to load environment variables from a .env file; if unsuccessful, set them manually.\n",
    "if not load_dotenv():\n",
    "    set_env(\n",
    "        {\n",
    "            \"OPENAI_API_KEY\": \"\",\n",
    "            \"LANGCHAIN_API_KEY\": \"\",\n",
    "            \"LANGCHAIN_TRACING_V2\": \"true\",\n",
    "            \"LANGCHAIN_ENDPOINT\": \"https://api.smith.langchain.com\",\n",
    "            \"LANGCHAIN_PROJECT\": \"LangGraph Subgraph\",\n",
    "        }\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aa00c3f4",
   "metadata": {},
   "source": [
    "## Case 1: When Sharing Schema Keys\n",
    "\n",
    "### Adding Nodes with Compiled SubGraphs\n",
    "\n",
    "It's a common case where the parent graph and subgraph communicate through shared state keys.\n",
    "For example, in multi-agent systems, agents typically communicate through a shared '```messages```' key.\n",
    "When a **subgraph shares state keys with the parent graph**, you can add it to the graph following these steps:\n",
    "\n",
    "1. Define and compile the ```subgraph``` workflow (```subgraph_builder``` in the example below)\n",
    "2. Pass the compiled ```subgraph``` to the ```.add_node``` method when defining the parent graph workflow"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "d34eac13",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langgraph.graph import START, END, StateGraph\n",
    "from typing import TypedDict\n",
    "\n",
    "\n",
    "# TypedDict class for defining subgraph state, including name key shared with parent graph and family_name key exclusive to subgraph\n",
    "class ChildState(TypedDict):\n",
    "    name: str  # State key shared with parent graph\n",
    "    family_name: str\n",
    "\n",
    "\n",
    "# First node of subgraph, sets initial value for family_name key\n",
    "def subgraph_node_1(state: ChildState):\n",
    "    return {\"family_name\": \"Lee\"}\n",
    "\n",
    "\n",
    "# Second node of subgraph, combines subgraph-exclusive family_name key and shared name key to create new state\n",
    "def subgraph_node_2(state: ChildState):\n",
    "    # Perform update using family_name key only available within subgraph and shared state key name\n",
    "    return {\"name\": f'{state[\"name\"]} {state[\"family_name\"]}'}\n",
    "\n",
    "\n",
    "# Define subgraph structure and set node connection relationships\n",
    "subgraph_builder = StateGraph(ChildState)\n",
    "subgraph_builder.add_node(subgraph_node_1)\n",
    "subgraph_builder.add_node(subgraph_node_2)\n",
    "subgraph_builder.add_edge(START, \"subgraph_node_1\")\n",
    "subgraph_builder.add_edge(\"subgraph_node_1\", \"subgraph_node_2\")\n",
    "subgraph = subgraph_builder.compile()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d17ce698",
   "metadata": {},
   "source": [
    "Visualize the Graph."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "715a67e6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from langchain_opentutorial.graphs import visualize_graph\n",
    "\n",
    "visualize_graph(subgraph, xray=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "377676b8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TypedDict class for defining parent graph state, containing only the name key\n",
    "class ParentState(TypedDict):\n",
    "    name: str\n",
    "    company: str\n",
    "\n",
    "\n",
    "# First node of parent graph, modifies the name key value to create new state\n",
    "def node_1(state: ParentState):\n",
    "    return {\"name\": f'My name is {state[\"name\"]}'}\n",
    "\n",
    "\n",
    "# Define parent graph structure and set node connection relationships including subgraph\n",
    "builder = StateGraph(ParentState)\n",
    "builder.add_node(\"node_1\", node_1)\n",
    "# Add compiled subgraph as a node to parent graph\n",
    "builder.add_node(\"node_2\", subgraph)\n",
    "builder.add_edge(START, \"node_1\")\n",
    "builder.add_edge(\"node_1\", \"node_2\")\n",
    "builder.add_edge(\"node_2\", END)\n",
    "graph = builder.compile()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "d681db5f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "visualize_graph(graph, xray=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "0f378726",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'node_1': {'name': 'My name is Teddy'}}\n",
      "{'node_2': {'name': 'My name is Teddy Lee'}}\n"
     ]
    }
   ],
   "source": [
    "# Stream graph data chunk by chunk and print each chunk\n",
    "for chunk in graph.stream({\"name\": \"Teddy\"}):\n",
    "    print(chunk)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d6823547",
   "metadata": {},
   "source": [
    "The final output of the parent graph includes the results of the subgraph calls.\n",
    "\n",
    "To check the output of the subgraph, you can specify ```subgraphs=True``` when streaming."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "0817a4e0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "((), {'node_1': {'name': 'My name is Teddy'}})\n",
      "(('node_2:83ab5741-81c5-3032-fac4-c66046ee1e2c',), {'subgraph_node_1': {'family_name': 'Lee'}})\n",
      "(('node_2:83ab5741-81c5-3032-fac4-c66046ee1e2c',), {'subgraph_node_2': {'name': 'My name is Teddy Lee'}})\n",
      "((), {'node_2': {'name': 'My name is Teddy Lee'}})\n"
     ]
    }
   ],
   "source": [
    "# Stream and output subgraph data chunks sequentially\n",
    "# Process streaming with subgraphs by setting subgraphs=True\n",
    "for chunk in graph.stream({\"name\": \"Teddy\"}, subgraphs=True):\n",
    "    print(chunk)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "da26218e",
   "metadata": {},
   "source": [
    "## Case 2: When Not Sharing Schema Keys\n",
    "\n",
    "### Adding Node Functions That Call Subgraphs\n",
    "\n",
    "In more complex systems, you might need to **define subgraphs with completely different schemas from the parent graph** (cases where there are no shared state keys).\n",
    "\n",
    "In such cases, you need to define a node function that calls the ```subgraph```.\n",
    "\n",
    "This function must transform the parent state into child state before calling the ```subgraph```, and transform the results back into parent state before returning state updates from the node.\n",
    "\n",
    "Below, we'll show how to modify the original example to call the ```subgraph``` within a node.\n",
    "\n",
    "\n",
    "[**Note**]\n",
    "- You **cannot** call more than one subgraph within the same node."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "5fb3e924",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define subgraph state type (no shared keys with parent graph)\n",
    "class ChildState(TypedDict):\n",
    "    # Keys not shared with parent graph\n",
    "    name: str\n",
    "\n",
    "\n",
    "# First node of subgraph: sets initial value for name key\n",
    "def subgraph_node_1(state: ChildState):\n",
    "    return {\"name\": \"Teddy \" + state[\"name\"]}\n",
    "\n",
    "\n",
    "# Second node of subgraph: returns name value as is\n",
    "def subgraph_node_2(state: ChildState):\n",
    "    return {\"name\": f'My name is {state[\"name\"]}'}\n",
    "\n",
    "\n",
    "# Initialize subgraph builder and configure node connections\n",
    "subgraph_builder = StateGraph(ChildState)\n",
    "subgraph_builder.add_node(subgraph_node_1)\n",
    "subgraph_builder.add_node(subgraph_node_2)\n",
    "subgraph_builder.add_edge(START, \"subgraph_node_1\")\n",
    "subgraph_builder.add_edge(\"subgraph_node_1\", \"subgraph_node_2\")\n",
    "subgraph = subgraph_builder.compile()\n",
    "\n",
    "\n",
    "# Define parent graph state type\n",
    "class ParentState(TypedDict):\n",
    "    family_name: str\n",
    "    full_name: str\n",
    "\n",
    "\n",
    "# First node of parent graph: returns family_name value as is\n",
    "def node_1(state: ParentState):\n",
    "    return {\"family_name\": state[\"family_name\"]}\n",
    "\n",
    "\n",
    "# Second node of parent graph: handles state transformation with subgraph and processes results\n",
    "def node_2(state: ParentState):\n",
    "    # Transform parent state to subgraph state\n",
    "    response = subgraph.invoke({\"name\": state[\"family_name\"]})\n",
    "    # Transform subgraph response back to parent state\n",
    "    return {\"full_name\": response[\"name\"]}\n",
    "\n",
    "\n",
    "# Initialize parent graph builder and configure node connections\n",
    "builder = StateGraph(ParentState)\n",
    "builder.add_node(\"node_1\", node_1)\n",
    "\n",
    "# Use node_2 function that calls subgraph instead of compiled subgraph\n",
    "builder.add_node(\"node_2\", node_2)\n",
    "builder.add_edge(START, \"node_1\")\n",
    "builder.add_edge(\"node_1\", \"node_2\")\n",
    "builder.add_edge(\"node_2\", END)\n",
    "graph = builder.compile()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9bfdf139",
   "metadata": {},
   "source": [
    "Visualize the Graph"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "894cceff",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "visualize_graph(graph, xray=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "69cb77da",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "((), {'node_1': {'family_name': 'Lee'}})\n",
      "(('node_2:64295ff5-a73e-84c0-8221-a7621d6ee521',), {'subgraph_node_1': {'name': 'Teddy Lee'}})\n",
      "(('node_2:64295ff5-a73e-84c0-8221-a7621d6ee521',), {'subgraph_node_2': {'name': 'My name is Teddy Lee'}})\n",
      "((), {'node_2': {'full_name': 'My name is Teddy Lee'}})\n"
     ]
    }
   ],
   "source": [
    "# Stream and output subgraph data chunks sequentially\n",
    "# Process streaming with subgraphs by setting subgraphs=True\n",
    "for chunk in graph.stream({\"family_name\": \"Lee\"}, subgraphs=True):\n",
    "    print(chunk)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "langchain-kr-lwwSZlnu-py3.11",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
